﻿using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using StudentSys.Models;

namespace StudentSys.DAL
{
    /// <summary>
    /// where T : BaseEntity, new()限制了T的范围
    /// 实现了 IDisposable 接口，就得提供一个 Dispose 方法。在这个方法里，可以编写释放非托管资源的代码。用户在使用完这个类的实例后，能调用 Dispose 方法来释放资源，避免资源泄漏。
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class BaseService<T> : IDisposable where T : BaseEntity, new()
    {
        protected readonly StudentContext _db;
        public BaseService(StudentContext db)
        {
            _db = db;
        }
        public void Dispose()
        {
            _db.Dispose();
        }
        /// <summary>
        /// 实现异步的添加操作
        /// </summary>
        /// <param name="t"></param>
        /// <returns></returns>
        public async Task CreateAsync(T t, bool saved = true)
        {
            _db.Set<T>().Add(t);
            if (saved) { await _db.SaveChangesAsync(); }
        }
        public async Task SaveAsync(bool isValid = true)
        {
            if (!isValid)
            {
                _db.Configuration.ValidateOnSaveEnabled = false;
                await _db.SaveChangesAsync();
                _db.Configuration.ValidateOnSaveEnabled = true;

            }
            await _db.SaveChangesAsync();
        }
        /// <summary>
        /// 实现异步修改
        /// </summary>
        /// <param name="t"></param>
        /// <returns></returns>
        public async Task EditAsync(T t, bool saved = true)
        {
            _db.Entry(t).State = EntityState.Modified;
            if (saved)
            {
                await SaveAsync(false);
            }

        }

        /// <summary>
        /// 实现异步删除
        /// </summary>
        /// <param name="id"></param>
        /// <param name="saved"></param>
        /// <returns></returns>
        public async Task RemoveAsync(Guid id, bool saved = true)
        {
            var t = new T()
            {
                Id = id
            };
            _db.Entry(t).State = EntityState.Unchanged;
            t.IsRemoved = true;
            if (saved)
                await SaveAsync(false);
        }

        /// <summary>
        /// 进行查找
        /// </summary>
        /// <returns></returns>
        public IQueryable<T> GetAll()
        {
            return _db.Set<T>().AsNoTracking().Where(m => !m.IsRemoved);
        }
        public IQueryable<T> GetAll(Expression<Func<T, bool>> predicate)
        {
            return GetAll().Where(predicate);
        }
        /// <summary>
        /// 排序
        /// </summary>
        /// <param name="predicate"></param>
        /// <param name="asc"></param>
        /// <returns></returns>
        public IQueryable<T> GetAll(Expression<Func<T, bool>> predicate, bool asc)
        {
            var date = GetAll().Where(predicate);
            if (asc)
            {
                return date.OrderBy(m => m.CreatedTime);
            }
            else
            {
                return date.OrderByDescending(m => m.CreatedTime);
            }
        }
        /// <summary>
        /// 分页查询
        /// </summary>
        /// <param name="predicate"></param>
        /// <param name="asc"></param>
        /// <param name="pageSize"></param>
        /// <param name="pageIndex"></param>
        /// <returns></returns>
        public IQueryable<T> GetAll(Expression<Func<T, bool>> predicate, bool asc, int pageIndex, int pageSize = 10)
        {

            return GetAll(predicate, asc).Skip(pageSize).Take(pageIndex);
        }
        public async Task<T> GetOne(Guid id)
        {
            return await GetAll().FirstAsync(m => m.Id == id);
        }
    }
}
